<?php

/**
 * AmplifyCMS
 *
 * This file is part of AmplifyCMS.
 *
 * AmplifyCMS is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * AmplifyCMS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Rodrigo Rutkoski Rodrigues, <rutkoski@gmail.com>
 * @copyright Copyright 2008 Rodrigo Rutkoski Rodrigues
 */

/**
 * Amplify Application Controller
 *
 * @author Rodrigo Rutkoski Rodrigues, <rutkoski@gmail.com>
 */
class Amplify extends ApplicationControllerImpl
{

  const AUTH_MODE = self::AUTH_MODE_SESSION;

  const AUTH_MODE_SESSION = 'session';

  const AUTH_MODE_COOKIE = 'cookie';

  /**
   *
   * @var long
   */
  const NOT_INSTALLED = 999111;

  /**
   * Main menu.
   *
   * @var Menu
   */
  protected $menu;

  /**
   * Authenticated user.
   *
   * @var UserModel
   */
  protected $user;

  /**
   * These routes do not require authentication.
   *
   * @var array
   */
  private $unrestricted = array(
    '/home/index', '/login', '/logout', '/home/login', '/home/logout', '/install', '/amf/gateway' 
  );

  public function dispatch()
  {
    $route = Simplify::getRequest()->get('route');
    
    $db = OutletDAO::getInstance();
    $db->addEntity('Cap');
    $db->addEntity('Role');
    $db->addEntity('User');
    
    if (Session::getInstance()->has('notices')) {
      Simplify::getResponse()->notice(Session::getInstance()->get('notices'));
      Session::getInstance()->del('notices');
    }
    
    if (Session::getInstance()->has('warnings')) {
      Simplify::getResponse()->warning(Session::getInstance()->get('warnings'));
      Session::getInstance()->del('warnings');
    }
    
    try {
      if (! $this->isUnrestricted($route)) {
        $this->InitSession();
        
        Simplify::getL10n()->loadLanguageFile($this->user->locale);
        Simplify::getL10n()->setLocale($this->user->locale);
        
        $this->menu = new Menu($this);
        
        Modules::LoadActiveModules($this);
      }
      
      parent::dispatch();
    }
    
    catch (LoginRequiredException $e) {
      Session::getInstance()->set('original_route', $route != '/logout' ? $route : '/');
      return $this->forward('/login');
    }
    
    catch (PermissionException $e) {
      Simplify::getResponse()->warning($e->getMessage());
      return $this->forward('/');
    }
  }

  /**
   *
   * @return Menu
   */
  public function getMenu()
  {
    return $this->menu;
  }

  /**
   *
   * @return UserModel
   */
  public function getUser()
  {
    return $this->user;
  }

  /**
   *
   */
  public function isUnrestricted($route)
  {
    return in_array($route, $this->unrestricted) ? true : false;
  }

  /**
   *
   */
  public function Login($user)
  {
    $this->user = $user;
    
    if (self::AUTH_MODE == self::AUTH_MODE_SESSION) {
      Session::getInstance()->set('sid', session_id());
      Session::getInstance()->set('user_id', $user->id);
    }
    
    else if (self::AUTH_MODE == self::AUTH_MODE_COOKIE) {
      $time = time() + 3600;
      setcookie('amp_auth_sid', session_id(), $time, '/');
      setcookie('amp_auth_user_id', $user->id, $time, '/');
      setcookie('amp_auth_user_ip', getRealIpAddress(), $time, '/');
    }
  }

  /**
   *
   */
  protected function InitSession()
  {
    if (self::AUTH_MODE == self::AUTH_MODE_SESSION) {
      $login = true;
      if (Session::getInstance()->get('sid') != session_id() || ! Session::getInstance()->has('user_id')) {
        $login = false;
      }
      
      if ($login) {
        $this->user = OutletDAO::getInstance()->load('User', Session::getInstance()->get('user_id'));
      }
      
      else if (! $this->isUnrestricted(Simplify::getRequest()->get('route'))) {
        throw new LoginRequiredException('Not logged in'); //, SecurityException::NOT_LOGGED_IN);
      }
    }
    
    else if (self::AUTH_MODE == self::AUTH_MODE_COOKIE) {
      $login = true;
      if (! isset($_COOKIE['amp_auth_sid']) || $_COOKIE['amp_auth_sid'] != session_id() || ! isset($_COOKIE['amp_auth_user_id']) || $_COOKIE['amp_auth_user_ip'] != getRealIpAddress()) {
        $login = false;
      }
      
      if ($login) {
        $this->user = OutletDAO::getInstance()->load('User', $_COOKIE['amp_auth_user_id']);
      }
      
      else if (! $this->isUnrestricted(Simplify::getRequest()->get('route'))) {
        throw new LoginRequiredException('Not logged in'); //, SecurityException::NOT_LOGGED_IN);
      }
    }
  }

  /**
   *
   */
  public function Logout()
  {
    $this->checkLogin();
    
    $time = time() - 3600;
    setcookie('amp_auth_sid', session_id(), $time, '/');
    setcookie('amp_auth_user_id', $this->getUser()->id, $time, '/');
    setcookie('amp_auth_user_ip', getRealIpAddress(), $time, '/');
    
    while (count($_COOKIE)) {
      array_pop($_COOKIE);
    }
    
    Session::getInstance()->destroy();
  }

  /**
   * 
   * @return void
   */
  public function checkLogin()
  {
    if (! $this->getUser()) {
      throw new LoginRequiredException('Not logged in');
    }
  }

}

?>